package com.evil.account.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.evil.account.pojo.entity.UserDepartment;
import com.evil.common.account.dto.FindByIdsAndEIdReqDTO;
import com.evil.common.account.dto.department.DepartmentBaseRespDTO;
import com.evil.common.account.dto.user.FindUserIdsByIdReqDTO;
import com.evil.common.account.dto.user.FindUserIdsByIdsReqDTO;
import com.evil.common.account.dto.user.UserBaseRespDTO;
import com.evil.common.account.dto.user.UserEnterpriseBaseDTO;
import com.evil.common.account.dto.user.department.UserDepartmentBaseRespDTO;
import com.evil.common.core.exception.BusinessException;
import com.evil.common.core.util.StreamUtil;
import com.evil.common.db.mapper.BatchMapper;
import com.evil.common.family.enums.RCodeEnum;
import org.apache.ibatis.annotations.Param;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author liyang
 * @date 2023-01-11 09:14
 */
public interface UserDepartmentMapper extends BaseMapper<UserDepartment>, BatchMapper<UserDepartment, Long> {

    int updateBatch(List<UserDepartment> list);

    int batchInsert(@Param("list") List<UserDepartment> list);

    default Optional<UserDepartment> isExistById(Long id) {
        return Optional.ofNullable(this.selectById(id));
    }

    default UserDepartment findById(Long id) {
        return this.isExistById(id).orElseThrow(() -> new BusinessException(RCodeEnum.USER_DEPARTMENT_NOT_EXIST));
    }

    List<UserDepartment> findByIds(@Param("ids") Collection<Long> ids, @Param("filterDeleted") boolean filterDeleted);

    default List<UserDepartment> findByIds(Collection<Long> ids) {
        return this.selectBatchIds(ids);
    }

    Optional<UserDepartment> findUserDepartment(@Param("userId") Long userId,
                                                @Param("departmentId") Long departmentId,
                                                @Param("filterDeleted") boolean filterDeleted);

    List<UserDepartment> findByUserId(@Param("enterpriseId") Long enterpriseId,
                                      @Param("userId") Long userId,
                                      @Param("filterDeleted") boolean filterDeleted);

    List<Long> findDeptIdsByUserId(@Param("enterpriseId") Long enterpriseId,
                                   @Param("userId") Long userId,
                                   @Param("filterDeleted") boolean filterDeleted);

    List<UserDepartment> findByDepartmentId(@Param("departmentId") Long departmentId, @Param("filterDeleted") boolean filterDeleted);

    List<UserDepartment> findByDepartmentIdUserIds(@Param("enterpriseId") Long enterpriseId,
                                                   @Param("departmentId") Long departmentId,
                                                   @Param("userIds") Collection<Long> userIds,
                                                   @Param("filterDeleted") boolean filterDeleted);

    List<Long> findUserIdsByDeptId(FindUserIdsByIdReqDTO findUserIdsByIdReqDTO);

    List<UserBaseRespDTO> findUserBasesByDeptIds(FindUserIdsByIdsReqDTO findUserIdsByIdsReqDTO);

    List<Long> findUserIdsByDeptIds(FindUserIdsByIdsReqDTO findUserIdsByIdsReqDTO);

    List<DepartmentBaseRespDTO> findByUserEnterprise(UserEnterpriseBaseDTO userEnterpriseDTO);

    List<UserDepartmentBaseRespDTO> findUserDepartmentBaseByUserEnterprise(UserEnterpriseBaseDTO userEnterpriseDTO);

    List<UserDepartmentBaseRespDTO> findUserDepartmentBaseByUserIds(FindByIdsAndEIdReqDTO findByIdsAndEIdReqDTO);

    default Map<Long, List<UserDepartmentBaseRespDTO>> findGroupUserDepartmentBaseByUserIds(FindByIdsAndEIdReqDTO findByIdsAndEIdReqDTO) {
        return StreamUtil.groupK(this.findUserDepartmentBaseByUserIds(findByIdsAndEIdReqDTO), UserDepartmentBaseRespDTO::getUserId);
    }
}
